package com.chenxbook.modules.jbpm4.assign;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jbpm.api.TaskService;
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
import org.jbpm.api.task.Task;

import java.text.MessageFormat;
import java.util.List;

/**
 * 基于"一票否决制"业务逻辑的会签任务提交命令
 */
public class SubmitJointlySignTaskCmd implements Command<Boolean> {
    private static final long serialVersionUID = 2274261332853376231L;

    //这个常量用来标识传递会签意见的"任务变量"名称
    public static final String VAR_SIGN = "Sign";
    //当会签通过时，流向的转移名称。由客户端通过构造方法传入
    private String transitionNamePass;
    //当会签否决时，流向的转移名称。由客户端通过构造方法传入
    private String transitionNameNoPass;
    //主任务ID.由客户端通过构造方法传入
    private String parentTaskId;
    //主任务对象。运行时计算得出
    private Task parentTask;
    //流程实例ID。运行时计算得出
    private String pid;
    //会签任务对象。有客户端通过setter方法注入
    private Task jointlySignTask;

    public void setJointlySignTask(Task jointlySignTask) {
        this.jointlySignTask = jointlySignTask;
    }

    public String getPid() {
        return pid;
    }

    public String getParentTaskId() {
        return parentTaskId;
    }

    //命令的构造方法。从客户端收集一些关键数据
    public SubmitJointlySignTaskCmd(String parentTaskId, String transitionNamePass, String transitionNameNoPass) {
        this.parentTaskId = parentTaskId;
        this.transitionNamePass = transitionNamePass;
        this.transitionNameNoPass = transitionNameNoPass;
    }

    @Override
    public Boolean execute(Environment environment) throws Exception {
        TaskService taskService = environment.get(TaskService.class);
        //计算出主任务和流程实例ID
        this.parentTask = taskService.getTask(parentTaskId);
        this.pid = parentTask.getExecutionId();
        //获取当前的会签任务
        String jointlySignTaskId = jointlySignTask.getId();
        //从当前会签任务的任务变量中获取"会签意见"
        String sign = (String) taskService.getVariable(jointlySignTaskId, VAR_SIGN);
        //在这里设定一个规则：如果会签意见为"false"、"no"、或"不同意"，则表示否决
        if (StringUtils.isNotBlank(sign) && (sign.equalsIgnoreCase("false") ||
                sign.equalsIgnoreCase("no") || sign.equals("不同意")
        )) {
            //根据"一票否决"的业务逻辑，一旦会签存在否定意见，则会签活动结束。具体实现如下：
            //首先结束会签任务
            taskService.completeTask(jointlySignTaskId);
            //然后，为主任务增加一条会签意见的注释记录，以备日后查询
            String taskComment = MessageFormat.format("user: {0}, Sign: {1}", jointlySignTask.getAssignee(), sign);
            taskService.addTaskComment(parentTaskId, taskComment);
            //最后，结束主任务并流向预先定义的会签否决转移
            taskService.completeTask(parentTaskId, transitionNameNoPass);
            //返回true到客户端。表示会签活动结束。
            return true;
        }
        //以下是会签任务的肯定意见时的处理逻辑:
        //完成会签任务
        taskService.completeTask(jointlySignTaskId);
        //然后，为主任务增加一条会签意见的注释记录，以备日后查询
        String taskComment = MessageFormat.format("user: {0}, Sign: {1}", jointlySignTask.getAssignee(), sign);
        taskService.addTaskComment(parentTaskId, taskComment);
        //判断是否还有会签"子任务"
        List<Task> subTasks = taskService.getSubTasks(parentTaskId);
        if (CollectionUtils.isEmpty(subTasks)) {
            //若已无会签"子任务"，则表明会签全体同意，会签活动结束，需要：结束主任务，并流向会签通过转移。
            taskService.completeTask(parentTaskId, transitionNamePass);
            //返回true客户端。表示会签活动结束
            return true;
        }
        //返回false到客户端。表示会签活动未结束，继续进行
        return false;
    }
}
